/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package modele;


import position.PositionPassage;
import position.PositionChamp;
import java.awt.Graphics;
import java.awt.Point;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.JPanel;

/**
 *
 * @author DONG Xiangxiang
 */
public class Bergerie extends JPanel{
    private double COTE;
    private Point pointCentral;
    private Map<Integer,List<Point>> pointsCentrauxChamp;
    private Map<Integer,List<Champ>> champs;
    private Map<Integer,List<Point>> pointsCentrauxPassageVertical;
    private Map<Integer,List<Passage>> passagesVertical;
    private Map<Integer,List<Point>> pointsCentrauxPassageIncline;
    private Map<Integer,List<Passage>> passagesIncline;
    private int nbRang;  
    private Barriere barriere=new Barriere();
    public  Bergerie(){
        this(4);
    }
     public Bergerie(int nbRang){
        super();
        this.nbRang=nbRang;
        this.setSize(nbRang*230, nbRang*230);
        COTE=Champ.getCOTE();
        pointCentral = new Point(this.getWidth()/2,this.getHeight()/2);
        pointsCentrauxChamp = getPointsCentrauxChamp();
        pointsCentrauxPassageVertical = getPointsCentrauxPassageVertical();
        pointsCentrauxPassageIncline = getPointsCentrauxPassageIncline();
        champs = new HashMap<Integer,List<Champ>>();
        passagesVertical = new HashMap<Integer,List<Passage>>();
        passagesIncline = new HashMap<Integer,List<Passage>>();
        setBorder(BorderFactory.createTitledBorder("Bergerie")); 
        
    }

     public void paintComponent(Graphics g) {
        barriere.paint(g,50,50);
        for(int i=0; i<pointsCentrauxChamp.size(); i++) {
            List<Point> points = pointsCentrauxChamp.get(i);
            List<Champ> champsTmp= new ArrayList<Champ>();
            for(int k=0; k<points.size();k++)
            {
                Champ champ= new Champ(points.get(k));
                champ.setIndex(i, k);
                champ.paint(g);
                champsTmp.add(champ);          
            }
            champs.put(i, champsTmp);
        }
        for(int i=0; i<pointsCentrauxPassageVertical.size(); i++) {
            List<Point> points = pointsCentrauxPassageVertical.get(i);
            List<Passage> passagesVerticalTmp= new ArrayList<Passage>();
            for(int k=0; k<points.size();k++)
            {
                Passage passage= new Passage(points.get(k),Math.PI/4);
                passage.setIndex(i, k);
                passage.paint(g);
                passagesVerticalTmp.add(passage);           
            }
            passagesVertical.put(i, passagesVerticalTmp);
        }
        for(int i=0;i<nbRang-1;i++){
            List<Point> points = pointsCentrauxPassageIncline.get(i);
            List<Passage> passagesInclineTmp= new ArrayList<Passage>();
            for(int k=0; k<points.size();k++)
            {
                Passage passage= new Passage(points.get(k),Math.PI*5/12);
                passage.setIndex(i, k);
                passage.paint(g);
                passagesInclineTmp.add(passage);
                k++;
                passage= new Passage(points.get(k),Math.PI*7/12);
                passage.setIndex(i, k);
                passage.paint(g);
                passagesInclineTmp.add(passage);
            }
            passagesIncline.put(i, passagesInclineTmp);
        }
        for(int i=nbRang-1;i<pointsCentrauxPassageIncline.size();i++){
            List<Point> points = pointsCentrauxPassageIncline.get(i);
            List<Passage> passagesInclineTmp= new ArrayList<Passage>();
            for(int k=0; k<points.size();k++)
            {
                Passage passage= new Passage(points.get(k),Math.PI*7/12);
                passage.setIndex(i, k);
                passage.paint(g);
                passagesInclineTmp.add(passage); 
                k++;
                passage= new Passage(points.get(k),Math.PI*5/12);
                passage.setIndex(i, k);
                passage.paint(g);
                passagesInclineTmp.add(passage);
            }
            passagesIncline.put(i, passagesInclineTmp);
        } 
        relierChampsEtPassages();
     }
    private Map<Integer, List<Point>> getPointsCentrauxChamp() {
        Map<Integer, List<Point>> pointsCentraux= new HashMap<Integer, List<Point>>();
        double distanceHorizontale= (Math.sqrt(3)+3)/2*COTE;
        double distanceVerticale=(Math.sqrt(3)+1)*COTE;
        int ox=(int)(pointCentral.x-(nbRang-1)*distanceHorizontale);
        int oy=(int)(pointCentral.y+(nbRang-1)*distanceVerticale/2);
        int nbChampParColonne=nbRang-1;
        int x, y;
        for(int i=0;i<nbRang;i++)
        {
            List<Point> points= new ArrayList<Point>();
            x=(int)(ox+i*distanceHorizontale);
            y=(int)(oy+i*distanceVerticale/2);
            nbChampParColonne++;
            for(int k=0;k<nbChampParColonne;k++)
            {
                points.add(new Point(x,y));
                y=(int)(y-distanceVerticale);
            }
            pointsCentraux.put(i, points);
            
        }
        ox=(int)(pointsCentraux.get(nbRang-1).get(0).getX());
        oy=(int)(pointsCentraux.get(nbRang-1).get(0).getY());
        for(int i=nbRang;i<nbRang*2-1;i++)
        {
            List<Point> points= new ArrayList<Point>();
            x=(int)(ox+(i-nbRang+1)*distanceHorizontale);
            y=(int)(oy-(i-nbRang+1)*distanceVerticale/2);
            nbChampParColonne--;
            for(int k=0;k<nbChampParColonne;k++)
            {
                points.add(new Point(x,y));
                y=(int)(y-distanceVerticale);
            }
            pointsCentraux.put(i, points);
            
        }
        return pointsCentraux;
    }

    private Map<Integer, List<Point>> getPointsCentrauxPassageVertical() {
        
        Map<Integer, List<Point>> passagesDroit = new HashMap<Integer, List<Point>>();
        for(int i=0;i<pointsCentrauxChamp.size();i++)
        {
            List<Point> pointsChamp = pointsCentrauxChamp.get(i);
            List<Point> pointsPassage= new ArrayList<Point>();
            int x = (int)(pointsChamp.get(0).x);
            for(int k=0;k<pointsChamp.size()-1;k++)
            {
                int y = (int)((pointsChamp.get(k).y+pointsChamp.get(k+1).y)/2);
                pointsPassage.add(new Point(x,y));           
            }
            passagesDroit.put(i, pointsPassage); 
        }
        return passagesDroit;
    }

    private Map<Integer, List<Point>> getPointsCentrauxPassageIncline() {
         Map<Integer, List<Point>> passages= new HashMap<Integer, List<Point>>();
         
         for(int i=0;i<nbRang-1;i++)
         {
            List<Point> pointsChampsColonneActuel = pointsCentrauxChamp.get(i);
            List<Point> pointsChampsColonneSuivant = pointsCentrauxChamp.get(i+1);
            List<Point> pointsPassage = new ArrayList<Point>();
            for(int k=0;k<pointsChampsColonneActuel.size();k++)
            {
                int x = (int) ((pointsChampsColonneActuel.get(k).x+pointsChampsColonneSuivant.get(k).x)/2);
                int y = (int) ((pointsChampsColonneActuel.get(k).y+pointsChampsColonneSuivant.get(k).y)/2);
                pointsPassage.add(new Point(x,y));
                x = (int) ((pointsChampsColonneActuel.get(k).x+pointsChampsColonneSuivant.get(k+1).x)/2);
                y = (int) ((pointsChampsColonneActuel.get(k).y+pointsChampsColonneSuivant.get(k+1).y)/2);
                pointsPassage.add(new Point(x,y));
            }
            passages.put(i, pointsPassage);
         }
         for(int i=nbRang-1;i<(nbRang-1)*2;i++)
         {
            List<Point> pointsChampsColonneActuel = pointsCentrauxChamp.get(i);
            List<Point> pointsChampsColonneSuivant = pointsCentrauxChamp.get(i+1);
            List<Point> pointsPassage = new ArrayList<Point>();
            for(int k=0;k<pointsChampsColonneSuivant.size();k++)
            {
                int x = (int) ((pointsChampsColonneSuivant.get(k).x+pointsChampsColonneActuel.get(k).x)/2);
                int y = (int) ((pointsChampsColonneSuivant.get(k).y+pointsChampsColonneActuel.get(k).y)/2);
                pointsPassage.add(new Point(x,y));
                x = (int) ((pointsChampsColonneSuivant.get(k).x+pointsChampsColonneActuel.get(k+1).x)/2);
                y = (int) ((pointsChampsColonneSuivant.get(k).y+pointsChampsColonneActuel.get(k+1).y)/2);
                pointsPassage.add(new Point(x,y));
            }
            passages.put(i, pointsPassage);
         }
         return passages;
    }
    public void relierChampsEtPassages(){
         for(int i=0;i<passagesVertical.size();i++)
        {
            for(int k=0;k<passagesVertical.get(i).size();k++)
            {
                passagesVertical.get(i).get(k).setChamps(PositionChamp.HAUT, champs.get(i).get(k));
                champs.get(i).get(k).setPassages(PositionPassage.SUD, passagesVertical.get(i).get(k));
                passagesVertical.get(i).get(k).setChamps(PositionChamp.BAS, champs.get(i).get(k+1));  
                champs.get(i).get(k+1).setPassages(PositionPassage.NORD, passagesVertical.get(i).get(k));
            }
        }    
        for(int i=0;i<((champs.size()-1)/2);i++)
        {
            int k = 0;
            for(int j=0;j<champs.get(i).size();j++)
            {
                passagesIncline.get(i).get(k).setChamps(PositionChamp.HAUT, champs.get(i+1).get(j));
                champs.get(i+1).get(j).setPassages(PositionPassage.SUDOUEST, passagesIncline.get(i).get(k));
                passagesIncline.get(i).get(k).setChamps(PositionChamp.BAS, champs.get(i).get(j));
                champs.get(i).get(j).setPassages(PositionPassage.NORDEST, passagesIncline.get(i).get(k));
                k++;
                passagesIncline.get(i).get(k).setChamps(PositionChamp.HAUT, champs.get(i).get(j));
                champs.get(i).get(j).setPassages(PositionPassage.SUDEST, passagesIncline.get(i).get(k));
                passagesIncline.get(i).get(k).setChamps(PositionChamp.BAS, champs.get(i+1).get(j+1));
                champs.get(i+1).get(j+1).setPassages(PositionPassage.NORDOUEST, passagesIncline.get(i).get(k));
                k++;
            }
        }
        for(int i=((champs.size()+1)/2);i<champs.size();i++)
        {
            int k = 0;
            for(int j=0;j<champs.get(i).size();j++)
            {
                passagesIncline.get(i-1).get(k).setChamps(PositionChamp.HAUT, champs.get(i-1).get(j));
                champs.get(i-1).get(j).setPassages(PositionPassage.SUDEST, passagesIncline.get(i-1).get(k));
                passagesIncline.get(i-1).get(k).setChamps(PositionChamp.BAS, champs.get(i).get(j));
                champs.get(i).get(j).setPassages(PositionPassage.NORDOUEST,passagesIncline.get(i-1).get(k) );
                k++;
                passagesIncline.get(i-1).get(k).setChamps(PositionChamp.HAUT, champs.get(i).get(j));
                champs.get(i).get(j).setPassages(PositionPassage.SUDOUEST, passagesIncline.get(i-1).get(k));
                passagesIncline.get(i-1).get(k).setChamps(PositionChamp.BAS, champs.get(i-1).get(j+1));
                champs.get(i-1).get(j+1).setPassages(PositionPassage.NORDEST, passagesIncline.get(i-1).get(k));
                k++;
            }
        }
    }
    public Object dansQuelElement(Point p){
        for(int i=0; i<champs.size(); i++) {
            List<Champ> champsParColonne = champs.get(i);
            for(int k=0; k<champsParColonne.size();k++)
            {
                if(champsParColonne.get(k).contains(p)) 
                    return champsParColonne.get(k);
            }
        }
        for(int i=0; i<passagesVertical.size(); i++) {
            List<Passage> passagesParColonne = passagesVertical.get(i);
            for(int k=0; k<passagesParColonne.size();k++)
            {
                if(passagesParColonne.get(k).contains(p)) 
                    return passagesParColonne.get(k);
            }
        }
        for(int i=0; i<passagesIncline.size(); i++) {
            List<Passage> passagesParColonne = passagesIncline.get(i);
            for(int k=0; k<passagesParColonne.size();k++)
            {
                if(passagesParColonne.get(k).contains(p)) 
                    return passagesParColonne.get(k);
            }
        }
        return null;
    }
    
    public void setChamp(Champ champ, Mouton mouton){
        for(int i=0; i<champs.size(); i++) {
            List<Champ> champsParColonne = champs.get(i);
            for(int k=0; k<champsParColonne.size();k++)
            {
                if(champsParColonne.get(k).equals(champ)) 
                {
                    champsParColonne.get(k).setMouton(mouton);
                    champsParColonne.get(k).setDisponible(false);
                }
            }
        }
    }
    
    public void setPassage(Passage passage){
        for(int i=0; i<passagesVertical.size(); i++) {
            List<Passage> passagesParColonne = passagesVertical.get(i);
            for(int k=0; k<passagesParColonne.size();k++)
            {
                if(passagesParColonne.get(k).equals(passage)) 
                   passagesParColonne.get(k).setDisponible(false);
            }
        }
        for(int i=0; i<passagesIncline.size(); i++) {
            List<Passage> passagesParColonne = passagesIncline.get(i);
            for(int k=0; k<passagesParColonne.size();k++)
            {
                if(passagesParColonne.get(k).equals(passage)) 
                    passagesParColonne.get(k).setDisponible(false);
            }
        }
    }
    
    public Map<Integer, List<Champ>> getChamps() {
        return champs;
    }
    public int getNbRang(){
        return nbRang;
    }
}
